package com.ruoyi.web.controller.system;

import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.web.service.PermissionService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 短信服务
 * @author 刘巍
 * @date 2021/07/07
 *
 */
@RestController
public class SysSmsController extends BaseController {
    // 注入RedisTemplate
    @Resource
    private RedisTemplate<Object, Object> redisTemplate;
    // 注入用户服务
    @Resource
    private ISysUserService userService;
    @Autowired
    private SysPermissionService permissionService;

    @Autowired
    private TokenService tokenService;

    /**
     * 获取短信验证码
     */
    @PostMapping("/smsCode")
    public AjaxResult getSmsCode(@RequestBody LoginBody loginBody )
    {
        // 获取前台传入的手机号
        String phone = loginBody.getPhone();
        // 校验手机号格式
        if (phone == null || !phone.matches("^1[3-9]\\d{9}$")) {
            return AjaxResult.error("请输入正确的手机号");
        }

        // 生成6位随机验证码
        String code = String.format("%06d", new Random().nextInt(999999));

        try {
            // 调用短信服务发送验证码（此处为示例，需替换为实际短信服务接口）
            // smsService.sendSms(phone, "您的验证码是：" + code + "，有效期5分钟，请妥善保管。");

            // 将验证码存入缓存，设置5分钟过期
            redisTemplate.opsForValue().set("sms:code:" + phone, code, 5, TimeUnit.MINUTES);
            // 打印日志（实际项目中建议使用日志框架）
            System.out.println("向手机号：" + phone + " 发送验证码：" + code);

            return AjaxResult.success("验证码发送成功,"+ code);
        } catch (Exception e) {
            // 发送失败处理
            System.err.println("验证码发送失败：" + e.getMessage());
            return AjaxResult.error("验证码发送失败，请稍后重试");
        }
    }
    /**
     * 验证码登录
     *
     */
    @PostMapping("/smsLogin")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
        // 获取手机号和验证码
        String phone = loginBody.getPhone();
        String code = loginBody.getCode();

        // 1. 校验手机号格式
        if (phone == null || !phone.matches("^1[3-9]\\d{9}$")) {
            return AjaxResult.error("请输入正确的手机号");
        }

        // 2. 校验验证码是否为空
        if (code == null || code.trim().isEmpty()) {
            return AjaxResult.error("请输入验证码");
        }

        // 3. 从Redis获取缓存的验证码
        String cacheKey = "sms:code:" + phone;
        String cachedCode = (String) redisTemplate.opsForValue().get(cacheKey);

        // 4. 验证验证码有效性
        if (cachedCode == null) {
            return AjaxResult.error("验证码已过期，请重新获取");
        }

        // 5. 比对验证码
        if (!cachedCode.equals(code)) {
            return AjaxResult.error("验证码不正确");
        }

        try {
            // 6. 根据手机号查询用户（核心补充）
            SysUser user = userService.selectUserByPhone(phone);
            if (user == null) {
                return AjaxResult.error("该手机号未注册");
            }
            LoginUser loginUser = new LoginUser();
            loginUser.setUser(user);
            Set<String> permissions  = permissionService.getMenuPermission(loginUser.getUser());
            loginUser.setPermissions(permissions); // 关键：设置权限到LoginUser
            String token = tokenService.createToken(loginUser);
            // 10. 移除已使用的验证码（防止重复使用）
            redisTemplate.delete(cacheKey);

            // 10. 保持与SysLoginController一致的返回格式
            AjaxResult ajax = AjaxResult.success();
            ajax.put("permissions", permissions);
            ajax.put(Constants.TOKEN, token);
            return ajax;
        } catch (Exception e) {
            System.err.println("登录失败：" + e.getMessage());
            return AjaxResult.error("登录失败，请稍后重试");
        }
    }
}
